Shader "XC/UI/ImageMask"
{
    Properties
    {
        _Color ("Tint", Color) = (1,1,1,1)
        [KeywordEnum(Square,Circle,Ellipse,RoundedRect)] USE_MASKSHAPE("Mask Shape", Float) = 0
        
        [Header(Square)]
        blurWidth ("blurWidth", Float) = 20
        _MaskRectPos1 ("MaskRectPos 1", vector) = (0,0,0,0)
        _MaskRectPos2 ("MaskRectPos 2", vector) = (0,0,0,0)
        
        [Header(Circle)]
        _MaskCirclePos1 ("MaskCirclePos 1(XY:CirclePos Z:Radius)", vector) = (0,0,0,0)
        _MaskCirclePos2 ("MaskCirclePos 2(XY:CirclePos Z:Radius)", vector) = (0,0,0,0)
        
        [Header(Ellipse)]
        _MaskEllipsePos("MaskEllipsePos(XY:Pos Z:Width W:Height)", Vector) = (0,0,200,100)
        _EllipseSmooth("Ellipse Smooth", float) = 0.2
        _EllipticEdge("Elliptic Edge", float) = 2
        
        [Header(Rounded Rectangle)]
        _RoundedRectPos1 ("Rounded Rect Pos 1 (XY: Min, ZW: Max)", Vector) = (0,0,100,100)
        _RoundedRectRadius1 ("Rounded Rect Radius 1", Float) = 10
        _RoundedRectBlurWidth1 ("Rounded Rect Blur Width 1", Float) = 5
        _RoundedRectPos2 ("Rounded Rect Pos 2 (XY: Min, ZW: Max)", Vector) = (0,0,100,100)
        _RoundedRectRadius2 ("Rounded Rect Radius 2", Float) = 10
        _RoundedRectBlurWidth2 ("Rounded Rect Blur Width 2", Float) = 5
        
        [Header(Stencil)]
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255
        
        _ColorMask ("Color Mask", Float) = 15
        
        [HideInInspector]_MainTex("MainTex",2D) = "white"{}
        
    }
    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }
        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }
        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            ZTest [unity_GUIZTestMode]
            Blend SrcAlpha OneMinusSrcAlpha
            ColorMask [_ColorMask]
            
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            #pragma multi_compile USE_MASKSHAPE_SQUARE USE_MASKSHAPE_CIRCLE USE_MASKSHAPE_ELLIPSE USE_MASKSHAPE_ROUNDEDRECT
            
            struct appdata
            {
                float4 vertex : POSITION;
                float4 color    : COLOR;
            };

            struct v2f
            {
                half4 color    : COLOR;
                float4 vertex : SV_POSITION;
                float4 worldPosition : TEXCOORD1;
            };
            
            uniform float4 _MaskRectPos1;
            uniform float4 _MaskRectPos2;
            uniform float4 _MaskCirclePos1;
            uniform float4 _MaskCirclePos2;
            uniform float4 _MaskEllipsePos;
            uniform float4 _RoundedRectPos1;
            uniform float _RoundedRectRadius1;
            uniform float _RoundedRectBlurWidth1;
            uniform float4 _RoundedRectPos2;
            uniform float _RoundedRectRadius2;
            uniform float _RoundedRectBlurWidth2;

            CBUFFER_START(UnityPerMaterial)
            half4 _Color;
            half _EllipseSmooth;
            float _EllipticEdge;
            float blurWidth;
            CBUFFER_END

            v2f vert (appdata v)
            {
                v2f OUT;
                OUT.worldPosition = v.vertex;
                OUT.color = v.color * _Color;
                OUT.vertex = TransformObjectToHClip(v.vertex.xyz);
                return OUT;
            }

            half4 frag (v2f IN) : SV_Target
            {
                float4 ObjPos = IN.worldPosition;
                
                float mask = 1;
                #ifdef USE_MASKSHAPE_SQUARE
                    // float2 inside = step(_MaskRectPos1.xy, ObjPos.xy) * step(ObjPos.xy, _MaskRectPos1.zw);
                    // float2 inside2 = step(_MaskRectPos2.xy, ObjPos.xy) * step(ObjPos.xy, _MaskRectPos2.zw);
                    // mask = (1 - inside.x * inside.y) * (1 - inside2.x * inside2.y);

                    // 模糊边缘宽度
                    // 矩形范围
                    float2 minBounds1 = _MaskRectPos1.xy;
                    float2 maxBounds1 = _MaskRectPos1.zw;
                    float2 minBounds2 = _MaskRectPos2.xy;
                    float2 maxBounds2 = _MaskRectPos2.zw;
                    // 对边界进行模糊处理
                    float2 distToEdge1 = saturate((ObjPos.xy - minBounds1) / blurWidth) * saturate((maxBounds1 - ObjPos.xy) / blurWidth);
                    float mask1 = distToEdge1.x * distToEdge1.y;
                    float2 distToEdge2 = saturate((ObjPos.xy - minBounds2) / blurWidth) * saturate((maxBounds2 - ObjPos.xy) / blurWidth);
                    float mask2 = distToEdge2.x * distToEdge2.y;
                    // 合并多个矩形遮罩
                    mask = (1 - mask1) * (1 - mask2);
                #endif
                #ifdef USE_MASKSHAPE_CIRCLE
                    float2 dir = ObjPos.xy - _MaskCirclePos1.xy;
                    float len = length(dir);
                    mask = smoothstep(_MaskCirclePos1.z - _MaskCirclePos1.w + 0.5, _MaskCirclePos1.z + _MaskCirclePos1.w + 0.5001, len);
                    float2 dir2 = ObjPos.xy - _MaskCirclePos2.xy;
                    float len2 = length(dir2);
                    mask *= smoothstep(_MaskCirclePos2.z - _MaskCirclePos2.w + 0.5, _MaskCirclePos2.z + _MaskCirclePos2.w + 0.5001, len2);
                #endif
                #ifdef USE_MASKSHAPE_ELLIPSE
                    float disX = distance(IN.worldPosition.x, _MaskEllipsePos.x);
                    float disY = distance(IN.worldPosition.y, _MaskEllipsePos.y);
                    float factor = pow(abs(disX / _MaskEllipsePos.z), _EllipticEdge) + pow(abs(disY / _MaskEllipsePos.w), _EllipticEdge);
                    float sub = 1 - saturate(smoothstep(factor - _EllipseSmooth ,factor + _EllipseSmooth + 0.01, 1));
                    mask = sub;
                #endif
                #ifdef USE_MASKSHAPE_ROUNDEDRECT
                    // 第一个圆角矩形
                    float2 minBounds1 = _RoundedRectPos1.xy;
                    float2 maxBounds1 = _RoundedRectPos1.zw;
                    float2 center1 = (minBounds1 + maxBounds1) * 0.5;
                    float2 size1 = maxBounds1 - minBounds1;
                    float2 pos1 = ObjPos.xy - center1;
                    float2 halfSize1 = size1 * 0.5;
                    float2 cornerDist1 = abs(pos1) - (halfSize1 - _RoundedRectRadius1);
                    float dist1 = length(max(cornerDist1, 0)) + min(max(cornerDist1.x, cornerDist1.y), 0);
                    float maskRounded1 = smoothstep(-_RoundedRectBlurWidth1, _RoundedRectBlurWidth1, dist1 - _RoundedRectRadius1);

                    // 第二个圆角矩形
                    float2 minBounds2 = _RoundedRectPos2.xy;
                    float2 maxBounds2 = _RoundedRectPos2.zw;
                    float2 center2 = (minBounds2 + maxBounds2) * 0.5;
                    float2 size2 = maxBounds2 - minBounds2;
                    float2 pos2 = ObjPos.xy - center2;
                    float2 halfSize2 = size2 * 0.5;
                    float2 cornerDist2 = abs(pos2) - (halfSize2 - _RoundedRectRadius2);
                    float dist2 = length(max(cornerDist2, 0)) + min(max(cornerDist2.x, cornerDist2.y), 0);
                    float maskRounded2 = smoothstep(-_RoundedRectBlurWidth2, _RoundedRectBlurWidth2, dist2 - _RoundedRectRadius2);

                    // 合并两个圆角矩形的挖空效果
                    mask = maskRounded1 * maskRounded2;
                #endif

                return mask * IN.color ;
            }
            ENDHLSL
        }
    }
}